#include "queue.h"
#include <string.h>

/******************************************************************************
 *函数名称：  queueInit
 *输入参数：  mem,连续的内存块地址，可以是数组，也可以是malloc分配的内存
 *            len,内存块size，不能比结构体QUEUE小
 * 			  typeSize,数据占内存大小
 *输出参数：  无
 *返回值  ：  Q_OK，初始化成功；Q_ERROR，初始化失败
 *功能描述：  初始化队列
 ******************************************************************************/
Q_RETURN queueInit(void* mem, int len, uint8_t typeSize)
{
	if(len < sizeof(QUEUE)) {	//如果数据块长度小于结构体长度
		return Q_ERROR;			//则初始化不成功
	}
	
	QUEUE* queue = (QUEUE*)mem;	//强制转成QUEUE指针结构
		
	queue->length = 0;			//数据量清零
	//计算最大数据量，柔性数组不计入结构体size
	//每个数据对应typeSize字节数据
	//相除之后，就是数据最大量
	queue->maxLength = (len - sizeof(QUEUE)) / typeSize;	
	queue->head = 0;			//头、尾索引清零
	queue->tail = 0;
	
	return Q_OK;				//返回初始化成功标志
}

/******************************************************************************
 *函数名称：  queueClear
 *输入参数：  mem,连续的内存块地址，可以是数组，也可以是malloc分配的内存
 *输出参数：  无
 *返回值  ：  Q_OK，初始化成功；Q_ERROR，初始化失败
 *功能描述：  清空队列
 ******************************************************************************/
Q_RETURN queueClear(void* mem)
{
	QUEUE* queue = (QUEUE*)mem;	//强制转成QUEUE指针结构
	
	queue->length = 0;			//数据量清零
	queue->head = 0;
	queue->tail = 0;
	return Q_OK;
}

/******************************************************************************
 *函数名称：  queuePush
 *输入参数：  mem,连续的内存块地址，可以是数组，也可以是malloc分配的内存
 *			  data,输入的数据
 * 			  typeSize,数据占内存大小
 *输出参数：  无
 *返回值  ：  Q_OK，写入成功；Q_FULL，队列满，写入失败
 *功能描述：  插入数据
 ******************************************************************************/
Q_RETURN queuePush(void* mem, const void *data, uint8_t typeSize)
{
	QUEUE* queue = (QUEUE*)mem;	//强制转成QUEUE指针结构
	
	//如果数据量已经满了，则插入失败
	if(queue->length >= queue->maxLength) {
		return Q_FULL;
	}
	
	//通过memcpy把传入指针复制到数组对应的位置
	memcpy(&(queue->dataArr[queue->head]), data, typeSize);	//插入数据
	queue->head += typeSize;				//头索引+typeSize
	queue->length++;						//数据量+1
	
	//如果头数据索引大于数组长度，则返回数组首位置
	queue->head = (queue->head)  % (typeSize * (queue->maxLength));
	
	return Q_OK;
}

/******************************************************************************
 *函数名称：  queuePull
 *输入参数：  mem,连续的内存块地址，可以是数组，也可以是malloc分配的内存	
 * 			  typeSize,数据占内存大小
 *输出参数：  data,读取的数据
 *返回值  ：  Q_OK，读取成功；Q_EMPTY，队列空，读取失败
 *功能描述：  读取数据
 ******************************************************************************/
Q_RETURN queuePull(void* mem, void *data, uint8_t typeSize)
{
	QUEUE* queue = (QUEUE*)mem;	//强制转成QUEUE指针结构
	
	if(queue->length == 0) {
		return Q_EMPTY;
	}
	
	//*data = queue->dataArr[queue->tail];	//弹出数据	
	memcpy(data, &(queue->dataArr[queue->tail]), typeSize);
	queue->tail += typeSize;
	queue->length--;
	
	//如果尾数据索引大于数组长度，则返回数组首位置
	queue->tail = (queue->tail) % (typeSize * (queue->maxLength));
	
	return Q_OK;
}




